#pragma once

#include "Types.h"
#include "DLL.h"
#include "Action.h"
#include <MyFC/Event.h>

namespace My {

class Layer : public virtual EventDispatcher
{
public:
	virtual ~Layer() { }
public:
	virtual bool IsEmpty() const = 0;
	virtual bool IsSelected() const = 0;
	virtual Size GetSourceDuration() const = 0;
	virtual int GetSourceOffset() const = 0;
	virtual Span GetTrimming() const = 0;
	virtual void SetSourceOffset(int) = 0;
	virtual void SetTrimming(Span) = 0;
	virtual void Select(bool) = 0;
public:
	/// Combines SourceOffset and SourceDuration
	Span GetSourceSpan() const; 
	/// In point is the first non-trimmed frame
	int GetIn() const;
	/// Out point is the last non-trimmed frame
	int GetOut() const;
	/// Duration of the non-trimmed part
	int GetDuration() const;
	/// Offset of the first non-trimmed frame
	int GetOffset() const;
	/// Combination of Offset and Duration
	Span GetSpan() const;
public:
	class Event : public My::Event {
	public:
		Layer &	m_Layer;
		Event(Layer & l) : m_Layer(l) { }
	};
	class TimeSpanChange : public Event {
	public:
		TimeSpanChange(Layer & l) : Event(l) { }
	};
	class TrimmingChange : public Event {
	public:
		TrimmingChange(Layer & l) : Event(l) { }
	};
	class StateChange : public Event {
	public:
		StateChange(Layer & l) : Event(l) { }
	};
};

// Inline implementations

inline Span Layer::GetSourceSpan() const
	{ return Span(0, int(GetSourceDuration())).Offset(GetSourceOffset()); }

inline int Layer::GetIn() const
	{ return GetTrimming().first; }

inline int Layer::GetOut() const
	{ return GetTrimming().last; }

inline int Layer::GetDuration() const
	{ return GetTrimming().Size(); }

inline int Layer::GetOffset() const
	{ return GetSourceOffset() + GetIn(); }

inline Span Layer::GetSpan() const
	{ return Span(0, GetDuration()).Offset(GetOffset()); }

} // My
